package com.tansun.easycare.rule.ruletest.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.RecursiveAction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;
import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.monitorjbl.xlsx.StreamingReader;
import com.tansun.easycare.core.config.Global;
import com.tansun.easycare.rule.common.Constant;
import com.tansun.easycare.rule.common.ResMessage;
import com.tansun.easycare.rule.common.enums.ContentTypeEnum;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.common.service.RuleRefCommService;
import com.tansun.easycare.rule.common.service.impl.RuleBaseServiceImpl;
import com.tansun.easycare.rule.datamodel.entity.RuleDataDomain;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.referencedata.entity.RuleReferenceData;
import com.tansun.easycare.rule.referencedata.model.RuleDataModelVO;
import com.tansun.easycare.rule.referencedata.service.RuleReferenceDataService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruletest.dao.RuleTestDao;
import com.tansun.easycare.rule.ruletest.entity.RuleTest;
import com.tansun.easycare.rule.ruletest.model.DataSetVO;
import com.tansun.easycare.rule.ruletest.model.RuleBatchResult;
import com.tansun.easycare.rule.ruletest.model.RuleBatchResultVO;
import com.tansun.easycare.rule.ruletest.model.RuleInputVO;
import com.tansun.easycare.rule.ruletest.model.RuleTestMap;
import com.tansun.easycare.rule.ruletest.service.RuleBigDataTestService;
import com.tansun.easycare.rule.ruletest.service.RuleTestService;
import com.tansun.easycare.rule.utils.ExcelConstant;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.LoggerManager;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.MField;

@Service("RuleBigDataTestService")
public class RuleBigDataTestServiceImpl extends RuleBaseServiceImpl<RuleTestDao, RuleTest> implements RuleBigDataTestService {
    @Autowired
    private RuleReferenceDataService ruleReferenceDataService;
    @Autowired
    private DataBomService dataBomService;
    @Autowired
    private RuleTestService ruleTestService;
    @Autowired
	private RuleManageService ruleManageService;
    @Autowired
    private RuleRefCommService ruleRefCommService;


    private static final String R = "R";
    private static final String R1 = "R1";
    private static final String R2 = "R2";
    private static final String R3 = "R3";

    private static final String TYPE_CELL = "规则：";
    private static final String MODEL_CELL = "模型：";
    private static final String VERSION_CELL = "版本号：";
    private static final String DATA_CELL = "测试编号：";
    private static final String TESTTIME_CELL = "测试时间：";
    private static final String RESULT_CELL = "结果";

    private static final int ROW_VALIDATION_NUM = 200000;

    public static final int EXR_DROOL_EXR_RPE_SIZE = 20000;
    
    public  static  final  int  SHEET_MAX_CLOS_NUMS =20000;


    public static final String EXCLE_SUFFIX = ".xls";

    private SimpleDateFormat spf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void createBatchTest(RuleTest ruleTest) throws BizException {
        ruleTest.setTestType("1");
        ruleTest.setStatus("12");
        try {
        this.save(ruleTest);
        }catch(Exception e) {
        	e.printStackTrace();
        }

    }

    @Override
    public String[] createExcelTemp(String projectCode, RuleTest ruleTest) throws BizException {
        String downRoot = Global.getConfig("file.uploadRoot");

        String[] result = new String[2];

        String downNameString = downRoot + File.separator + projectCode + File.separator
                + RuleModelTypeEnum.getRuleModelTypeEnum(ruleTest.getModelType());

        String fileName = RuleModelTypeEnum.getName(ruleTest.getModelType());
        fileName = fileName + "_" + ruleTest.getRuleName();
        fileName = fileName + "_" + ruleTest.getVersion();
        try {
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        } catch (UnsupportedEncodingException e1) {
            LoggerManager.error("", e1, this.getClass());
        }
        File tmpFile = new File(downNameString);
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }

        String tmpPath = downNameString + File.separator + fileName + ".xlsx";
        result[0] = tmpPath;
        result[1] = fileName;
        File file = new File(tmpPath);
        //TODO 同一个规则版本删除后新增不生成新excle
        /*if (file.exists()) {

            return result;
        }*/
        List<String> list = new ArrayList<String>();

        JSONObject json = new JSONObject();
        List<Object> toplist = new ArrayList<Object>();
        toplist.add(TYPE_CELL + RuleModelTypeEnum.getName(ruleTest.getModelType()));

        toplist.add(MODEL_CELL + ruleTest.getRuleName());
        toplist.add(VERSION_CELL + ruleTest.getVersion());

        toplist.add(DATA_CELL + ruleTest.getId());
        json.put(R, toplist);
        list.add("");

        json.put(R1, list);
        List<Object> list2 = new ArrayList<Object>();
        list2.add("对象");
        json.put(R2, list2);
        List<Object> list3 = new ArrayList<Object>();
        list3.add("属性");
        json.put(R3, list3);

        int countAttr = 0;

        RuleReferenceData referenceData = new RuleReferenceData();
        referenceData.setCode(ruleTest.getModelCode());
        referenceData.setModelType(ruleTest.getModelType());
        referenceData.setVersion(ruleTest.getVersion());
        referenceData.setContentType(ContentTypeEnum.in.code);
        referenceData.setProjectCode(ruleTest.getProjectCode());
        List<RuleDataModelVO> dataModels = this.findReferenceData(referenceData);
        Map<String, RuleReferenceData> paramMap = new HashMap<String, RuleReferenceData>();
        for (RuleDataModelVO ruleDataModelVO : dataModels) {
        	for(RuleReferenceData ref:ruleDataModelVO.getAttrList()) {
        		paramMap.put(ruleDataModelVO.getClassName()+ref.getNamecn(),ref);
        	}
		}
        Map<Integer, RuleReferenceData> map = new HashMap<Integer, RuleReferenceData>();
        for (RuleDataModelVO dm : dataModels) {
            if (dm.getAttrList().size() > 0 && dm.getAttrList().get(0) != null) {
            	int size = 0;
                for (Entry<String ,RuleReferenceData> entry : paramMap.entrySet()) {
                	if(!dm.getClassName().equals(entry.getValue().getClassName())) 
                		continue;
                	if(list3.contains(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn()))
                		continue;
                	list3.add(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn());
                	map.put(countAttr, entry.getValue());
                    countAttr++;
                    size++;
        		}
                list2.add(dm.getClassNamecn() + "##" + size);
            }
        }
        if (countAttr > 1) {
            list.add("赋值##" + countAttr);
        } else {
            list.add("赋值");
        }

        XSSFWorkbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("new Sheet");
        CellStyle style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER); // 创建一个居中格式
        writeHeadText(json.getJSONArray(R), style, sheet.createRow(0), sheet);
        writeHeadText(json.getJSONArray(R1), style, sheet.createRow(1), sheet);

        writeHeadText(json.getJSONArray(R2), style, sheet.createRow(2), sheet);

        writeHeadText(json.getJSONArray(R3), style, sheet.createRow(3), sheet);
        if (countAttr >= 1) {
            for (int i = 1; i <= countAttr; i++) {
                addValidation(projectCode, sheet, i, map.get(i-1));
            }
        }
        try {
            FileOutputStream fout = new FileOutputStream(tmpPath);
            wb.write(fout);
            fout.close();
        } catch (Exception e) {
            //e.printStackTrace();
            LoggerManager.error("", e, this.getClass());
        }
        return result;

    }

    public static void writeHeadText(List<Object> getList, CellStyle style, Row row, Sheet sheet) {
        int preLength = 0;
        for (int i = 0; i < getList.size(); i++) {
            Cell cell = row.createCell((short) i + preLength);
            cell.setCellValue(getValue(getList.get(i).toString()));
            int lastColIndex = cell.getColumnIndex() + Integer.valueOf(getColSpan(getList.get(i).toString())) - 1;

            cell.setCellStyle(style);
            if ((cell.getColumnIndex()) < lastColIndex)
                sheet.addMergedRegion(new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), lastColIndex));

            preLength = preLength + Integer.valueOf(getColSpan(getList.get(i).toString())) - 1;
        }
    }

    private static String getValue(String linStr) {
        String reg = "(.*?(\\w*))\\#\\#(.*?(\\w*)).*?";
        if (linStr.matches(reg)) {
            Pattern pattern = Pattern.compile(reg);
            Matcher matcher = pattern.matcher(linStr);
            String group = new String();
            while (matcher.find()) {
                group = matcher.group(1);
                return group;
            }
        }
        return linStr;
    }

    private static String getColSpan(String lineStr) {
        String reg = ".*?\\#\\#(.*?(\\d*)).*?";
        if (lineStr.matches(reg)) {
            Pattern pattern = Pattern.compile(reg);
            Matcher matcher = pattern.matcher(lineStr);
            String group = new String();
            if (matcher.find()) {
                group = matcher.group(1);
                return group;
            }
        }
        return "1";
    }

    public void addValidation(String projectCode, Sheet sheet, int colNum, RuleReferenceData ab) throws BizException {

        int valType = 0;
        String items = new String();
        if (StringUtils.isNotBlank(ab.getDomainStr())) {
            items = ab.getDomainStr();
            String  dmStr = StringUtils.substring(items, 0,items.length() - 1);
            dmStr = dmStr +", -]";
            items = dmStr;
            valType = 0;
        } else if (ab.getDataType().equals("Long")) {
            if (StringUtils.isNotBlank(ab.getDomain())) {
                items = ab.getDomain();
                String  spStr =StringUtils.substring(items, 1,items.length() - 1);
                String[] args =   spStr.split(",");
                if (args !=null && args.length==1) {
                		 spStr = spStr+"9999999999";
                		 items = "["+spStr+"]";
                }
            } else {
                items = "[-999,9999999999]";  //by yangpingxia，2018.12.11修改，添加负数输入，扩大输入值范围
            }
            valType = 1;
        } else if (ab.getDataType().equals("Double")) {
            if (StringUtils.isNotBlank(ab.getDomain())) {
                items = ab.getDomain();
                String  spStr =StringUtils.substring(items, 1,items.length() - 1);
                String[] args =   spStr.split(",");
                if (args !=null && args.length==1) {
                		 spStr = spStr+"9999999999";
                		 items = "["+spStr+"]";
                }                
            } else {
                items = "[-999,9999999999]";   //2018.12.11修改，添加负数输入，扩大输入值范围
            }

            valType = 2;
        }
        if (items.length() > 2) {
            items = items.substring(1, items.length() - 1);
            addValidation(items.split(","), sheet, colNum, valType);  
        }

    }


    /**
     * @param valType 0 数组 1 整形 2 浮点
     */
    public static void addValidation(String[] listStr, Sheet sheet, int rowNum, int valType) {
    	if(listStr.length<=1) {  //2018.1203添加，遇空继续
    		return;
    	}
    	
        // DataValidationHelper helper = sheet..getDataValidationHelper();

        CellRangeAddressList regions = new CellRangeAddressList(4, ExcelConstant.ROW_VALIDATION_NUM, rowNum, rowNum);
        DataValidationHelper help = new XSSFDataValidationHelper((XSSFSheet)sheet);
        // 生成下拉框内容
        XSSFDataValidationConstraint constraint = null;
        switch (valType) {
            case 1:
                constraint = (XSSFDataValidationConstraint) help.createNumericConstraint(DVConstraint.ValidationType.INTEGER, DVConstraint.OperatorType.BETWEEN, StringUtils.isEmpty(listStr[0]) || listStr[0].equals("") ? "-999"
                        : listStr[0], StringUtils.isEmpty(listStr[1]) || listStr[1].equals("") ? "9999999" : listStr[1]);
                break;
            case 2:
                constraint = (XSSFDataValidationConstraint) help.createNumericConstraint(DVConstraint.ValidationType.DECIMAL, DVConstraint.OperatorType.BETWEEN, StringUtils.isEmpty(listStr[0]) || listStr[0].equals("") ? "-999"
                        : listStr[0], StringUtils.isEmpty(listStr[1]) || listStr[1].equals("") ? "9999999" : listStr[1]);
                break;
            default:
                constraint = (XSSFDataValidationConstraint) help.createExplicitListConstraint(listStr);
                break;
        }

        // 绑定下拉框和作用区域
        DataValidation data_validation = help.createValidation(constraint, regions);
        // 对sheet页生效
        sheet.addValidationData(data_validation);

    }

    
    @Override
    public ResMessage add(String projectCode, String id, InputStream file, String suffix) throws BizException {

        ResMessage res = new ResMessage();
        RuleTest ruleTest = this.get(id);
        FileOutputStream fout = null;
        Workbook wb = null;
        try {
            String uploadRoot = Global.getConfig("file.uploadRoot");
            String uploadPath = uploadRoot + "/" + projectCode + RuleTest.UPDATE_BASE_PATH;

            String tempPath = uploadPath + File.separator + ruleTest.getId() + suffix;
            File f = new File(uploadPath);
            // 创建文件夹
            if (!f.exists()) {
                f.mkdirs();
            }
            fout = new FileOutputStream(tempPath);
            byte[]  b  = new  byte[1024];
            while (file.read(b) >-1) {
            	fout.write(b);
            }
            fout.close();

            if (".xls".equals(suffix)) {
                wb = new HSSFWorkbook(file);
            } else {
            	wb =StreamingReader.builder().rowCacheSize(500).bufferSize(8192).open(new File(tempPath));
                //wb = new XSSFWorkbook(file);
            }
            //StreamingSheet
            System.out.println("读EXCEL----");
            Sheet sheet = wb.getSheetAt(0);
            RuleTest batchTest2 = getBatchTest(sheet);

//            res = checkoutData(projectCode, ruleTest, sheet);
//            String succs = res.getCode();
//
//            if (succs != null && !"success".equals(succs)) {
//                return res;
//            }

            if (!id.equals(batchTest2.getId())) {
                throw new BizException("E-100002");
            }

            
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
            throw new BizException(e, "");
        } finally {

            try {
                if (wb != null) {
                	wb.close();
                }
                file.close();
             
            } catch (Exception e2) {
                LoggerManager.error("", e2, this.getClass());
                res.setCode("fail");
                return res;
            }
        }

        return this.updateBatchTest(ruleTest);

    }

    private   Row    readThreeRow(Sheet  sheet,Row  threeRow) {
    	  if (threeRow != null)
    		  return  threeRow;
    	  Row  row  =null;
    	  int  rowNum =0;
    	  for (Iterator<Row> rows=sheet.rowIterator();rows.hasNext();) {
    		     row  = rows.next();
    		     rowNum = row.getRowNum();
    	         if (rowNum ==3) {
    	        	 break;
    	         }
    	  }
    	  if (row  != null)
    	     threeRow = row; 
    	  return  row;
    }
    
    private  void  readRow(List<Object> list, Sheet  sheet,int  rwNum) {
    	  Row  row  =null;
    	  int  rowNum =0;
	  	  for (Iterator<Row> rows=sheet.rowIterator();rows.hasNext();) {
			     row  = rows.next();
			     rowNum = row.getRowNum();
		         if (rowNum ==rwNum) {
		        	 break;
		         }
		  }
	   	  for ( int i=0;i<row.getLastCellNum();i++) {
			   Cell  cell  =  row.getCell(i);
			   if (cell !=null) {
				   list.add(cell.getStringCellValue());
			   }
			   
		  }
	  	  
    }
    
    private  List<List<Object>>  readInput(Sheet sheet ) {
    	  Row  row  =null;
    	  int  rowNum =0;
    	  List<List<Object>> inDatas = new  ArrayList<>();
	  	  for (Iterator<Row> rows=sheet.rowIterator();rows.hasNext();) {
			     row  = rows.next();
			     rowNum  =  row.getRowNum();
			     if (rowNum <4) {
			    	 continue;
			     }
			     List<Object>    ceList  = new  ArrayList<>();
			     inDatas.add(ceList);
			     for (int i=1;i<row.getLastCellNum();i++) {
			    	   Cell  cell  = row.getCell(i);
			    	   ceList.add(this.getInputVals(cell));
			     }
			     

		  }
	  	  return  inDatas;
    }

    
    public List<RuleDataModelVO> findReferenceData(RuleReferenceData referenceData) throws BizException {

        List<RuleDataModelVO> result = new ArrayList<>();

        RuleDataModelVO ruleDataModelVO = null;
        List<RuleReferenceData> list = new ArrayList<>();
        String projectCode = referenceData.getProjectCode();
        String code = referenceData.getCode();
        String version = referenceData.getVersion();
        Collection<RuleReferenceData> refList = new ArrayList<RuleReferenceData>();
		RuleManage  ruleInfo   = new   RuleManage();
		ruleInfo.setCode(code);
		ruleInfo.setVersion(version);
		ruleInfo.setProjectCode(projectCode);
		List<RuleManage> rmlist =this.ruleManageService.findList(ruleInfo);
		if (rmlist == null || rmlist.size()==0){
			throw  new  BizException("E-000600");
		}
        ruleReferenceDataService.findFuncReferenceDataList(ruleInfo, list,referenceData.getContentType());
        if (RuleModelTypeEnum.RuleFlow.code.equals(referenceData.getModelType())
        		||RuleModelTypeEnum.StrategyFlow.code.equals(referenceData.getModelType())) {
            list = this.ruleRefCommService.findRuleFlowReferenceData(projectCode, code, version, null,referenceData.getContentType());
            Collection<RuleReferenceData>  refdatas = this.ruleReferenceDataService.reDataModeRef(list);
            refList.addAll(refdatas);
            
        } else if (RuleModelTypeEnum.ExecutionBlock.code.equals(referenceData.getModelType())) {
            list = this.ruleRefCommService.findExcBlockRefData(projectCode, code, version);
            Collection<RuleReferenceData>  refdatas = this.ruleReferenceDataService.reDataModeRef(list);
            refList.addAll(refdatas);
        } else {
            this.ruleReferenceDataService.findReferenceDataList(projectCode,code,referenceData.getModelType(),version,referenceData.getContentType(),list,null);
            Collection<RuleReferenceData>  refdatas = this.ruleReferenceDataService.reDataModeRef(list);
            refList.addAll(refdatas);
        }  
        Map<String, RuleDataModelVO> map = new HashMap<String, RuleDataModelVO>();


        for (RuleReferenceData refData : refList) {
            ruleDataModelVO = map.get(refData.getClassName());
            if (ruleDataModelVO == null) {
                ruleDataModelVO = new RuleDataModelVO();
                ruleDataModelVO.setAttrList(new ArrayList<RuleReferenceData>());

                ruleDataModelVO.setClassName(refData.getClassName());
                ruleDataModelVO.setClassNamecn(refData.getClassNamecn());
                ruleDataModelVO.setParamType(refData.getContentType());
                map.put(refData.getClassName(), ruleDataModelVO);
                result.add(ruleDataModelVO);
            }

            ruleDataModelVO.getAttrList().add(refData);

        }
        return result;

    }

    

    private RuleTest getBatchTest(Sheet sheet) {
        RuleTest batchTest = new RuleTest();
        List<Object> toplist = new ArrayList<Object>();
        Iterator<Row> rows = sheet.rowIterator();
        if (rows.hasNext()) {//获取测试规则所属信息，包括：组件类型，测试模型，版本号，测试编号。
            Row row = rows.next();
            for(  Iterator<Cell>  cells= row.cellIterator();cells.hasNext();) {
            	Cell  cell = cells.next();
	            if ((StringUtils.isEmpty(cell.getStringCellValue()) || cell.getStringCellValue().equals(""))) {
	
	            } else {
	                toplist.add(cell.getStringCellValue());
	            }
            }
        }
        for (Object s : toplist) {
            if (s.toString().indexOf(TYPE_CELL) >= 0) {
                RuleModelTypeEnum typeEnum = RuleModelTypeEnum.getRuleModelTypeEnumByName(s.toString().replace(TYPE_CELL, "").trim());
                if (typeEnum != null)
                    batchTest.setModelType(typeEnum.code);
            }
            if (s.toString().indexOf(MODEL_CELL) >= 0)
                batchTest.setRuleName(s.toString().replace(MODEL_CELL, "").trim());

            if (s.toString().indexOf(VERSION_CELL) >= 0)
                batchTest.setVersion(s.toString().replace(VERSION_CELL, "").trim());
            if (s.toString().indexOf(DATA_CELL) >= 0)
                batchTest.setId(s.toString().replace(DATA_CELL, "").trim());
        }

        return batchTest;

    }

    private ResMessage checkoutData(String projectCode, RuleTest batchTest, Sheet sheet) throws Exception {
        ResMessage resMessage = new ResMessage("success", "");
        if (StringUtils.isBlank(batchTest.getModelType())) {
            resMessage.setMsg(resMessage.getMsg() + "<div>规则类型不能为空！</div>");
        }
        if (StringUtils.isBlank(batchTest.getModelCode())) {
            resMessage.setMsg(resMessage.getMsg() + "<div>规则模型不能为空！</div>");
        }
        if (StringUtils.isBlank(batchTest.getVersion())) {
            resMessage.setMsg(resMessage.getMsg() + "<div>规则版本不能为空！</div>");
        }

        String type = batchTest.getModelType();


        List<RuleReferenceData> inputList = new ArrayList<RuleReferenceData>();
//        RuleReferenceData referenceData = new RuleReferenceData();
//        referenceData.setCode(batchTest.getModelCode());
//        referenceData.setVersion(batchTest.getVersion());
//        referenceData.setModelType(type);
//        referenceData.setContentType(ContentTypeEnum.in.code);
//        inputList.addAll(ruleReferenceDataService.findReferenceDataList(referenceData));
//        
        inputList = this.ruleRefCommService.findRuleFlowReferenceData(projectCode, batchTest.getModelCode(), batchTest.getVersion(), null,ContentTypeEnum.in.code);

        if (inputList == null || inputList.size() == 0) {
            resMessage.setMsg(resMessage.getMsg() + "<div>模型文件不存在，请检查该上传文件第一行信息！</div>");
            return resMessage;
        }

        // 检测r3数据合法
        if (checkOutR3(sheet, inputList, resMessage,null) == false) {
            return resMessage;
        }

        // 数据检测，为空，数据类型等
//        checkOutInput(sheet, inputList, resMessage);

        return resMessage;
    }


    // 检测r3数据合法
    private boolean checkOutR3(Sheet sheet, List<RuleReferenceData> thendms, ResMessage res,Row  threeRow) {
        boolean flag_ = true;
        Map<String, String> atrrNameZhcnMap = AtrrNameZhcnMap(thendms);
        Row row = this.readThreeRow(sheet,threeRow);
        Cell  cell  =null;
        int i =0;
        for (Iterator<Cell> cells = row.cellIterator();cells.hasNext();) {
            boolean flag = false;
            cell  = cells.next();
            int  clmIndex =cell.getColumnIndex();
            if (clmIndex ==0) {
            	continue;
            }
            String stringCellValue = cell.getStringCellValue();
            if(StringUtils.isEmpty(stringCellValue)) {
            	flag = true;
            }else {
            	String key = atrrNameZhcnMap.get(stringCellValue);
                if (isMappingAtrrNameZhcn(key, stringCellValue, atrrNameZhcnMap)) {
                    flag = true;
                }
            }

            flag_ = flag;
            if (!flag) {
                res.setCode("fail");
                res.setMsg(res.getMsg() + "<div>第4行第" + i + "列属性名[" + cell.getStringCellValue() + "]不存在！</div>");
            }
            i++;
        }
        return flag_;
    }

    /**
     * 
     * @param thendms
     * @return
     */
    private Map<String, String> AtrrNameZhcnMap(List<RuleReferenceData> thendms) {
        Map<String, String> atrrNameZhcnMap = new HashMap<String, String>();
        for (RuleReferenceData dm : thendms) {
            atrrNameZhcnMap.put(dm.getClassName()+"."+dm.getNameen(), dm.getClassNamecn()+"."+dm.getNamecn());
            atrrNameZhcnMap.put(dm.getClassNamecn()+"."+dm.getNamecn(),dm.getClassName()+"."+dm.getNameen());

        }
        return atrrNameZhcnMap;
    }

    private boolean isMappingAtrrNameZhcn(String name, String Zhacn, Map<String, String> atrrNameZhcnMap) {
        if (atrrNameZhcnMap.containsKey(name)) {
            if (atrrNameZhcnMap.get(name).equals(Zhacn)) {
                return true;
            }
        }
        return false;
    }



    private  Object   getInputVals(Cell  cell) {
        if (cell == null) {
            return "";
          } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
              return cell.getNumericCellValue();
          } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
             return cell.getStringCellValue();
          } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
             return cell.getCellFormula();
          } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
             return "";
          } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
              return cell.getBooleanCellValue();
          } else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
            return  "";
          }else 
        	  return  cell.getStringCellValue();
    }
    
    
    private List<Object> getInputVals(Sheet sheet, int colNum) {
        List<Object> getInputVals = new ArrayList<Object>();
        Row  row  = null;
        for (Iterator<Row> rows = sheet.rowIterator();rows.hasNext();) {
            row  = rows.next();
            if (row.getRowNum()<=4) {
            	continue;
            }
        	Cell cell = row.getCell(colNum);
            if (cell == null) {
              getInputVals.add("");
            } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                getInputVals.add(cell.getNumericCellValue());
            } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
                getInputVals.add(cell.getStringCellValue());
            } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
                getInputVals.add(cell.getCellFormula());
            } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
                getInputVals.add("");
            } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
                getInputVals.add(cell.getBooleanCellValue());
            } else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
                getInputVals.add("");
            }
        }
        return getInputVals;
    }

    public boolean checkDomain(Object val, String domain) {
        if (StringUtils.isNumericSpace(val.toString())) {
            return false;
        }
        if (StringUtils.isBlank(domain)) {
            return false;
        }
        domain = domain.replace("[", "");
        domain = domain.replace("]", "");
        String[] listStr = domain.split(",");
        String min = StringUtils.isBlank(listStr[0]) ? "-999" : listStr[0];  //2018.12.11修改，扩大输入值范围
        String max = StringUtils.isBlank(listStr[1]) ? "9999999" : listStr[1];
        if ((Double) val >= Double.valueOf(min) && (Double) val <= Double.valueOf(max)) {

        } else {
            return false;
        }
        return true;
    }

    @Override
    public ResMessage addXlsx(String projectCode, String id, InputStream is) throws BizException {

        RuleTest batchTest = this.get(id);


        String uploadRoot = Global.getConfig("file.uploadRoot");
        String uploadPath = uploadRoot + "/" + projectCode + RuleTest.UPDATE_BASE_PATH;

        String tempPath = uploadPath + File.separator + batchTest.getId() + RuleBigDataTestServiceImpl.EXCLE_SUFFIX;
        File f = new File(uploadPath);
        // 创建文件夹
        if (!f.exists()) {
            f.mkdirs();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(tempPath);
            byte[] b = new byte[1024];
            while (is.read(b) != -1) {
                fos.write(b);
            }

        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {

                    e.printStackTrace();
                    throw new BizException(e, "E-005001");
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {

                    e.printStackTrace();
                    throw new BizException(e, "E-005001");
                }
            }
        }


        return updateBatchTest(batchTest);
    }


    private ResMessage updateBatchTest(RuleTest ruleTest) {
        ResMessage res = new ResMessage("success", "上传成功！");
        ruleTest.setStatus("10");
        this.save(ruleTest);

        return res;
    }

    /**
          * 测试Excel，并写入结果内容
     *
     * @param projectCode 项目编号
     * @param id          测试id
     */
    @SuppressWarnings("unchecked")
    @Override
    public void  testExcel(String projectCode, String id) throws BizException {
        RuleTest ruleTest = this.get(id);

        String uploadRoot = Global.getConfig("file.uploadRoot");
        String uploadPath = uploadRoot + "/" + projectCode + RuleTest.UPDATE_BASE_PATH;

        String tempPath = uploadPath + File.separator + ruleTest.getId() + RuleBigDataTestServiceImpl.EXCLE_SUFFIX;

        String filePathx = uploadPath + File.separator + ruleTest.getId() + ".xlsx";
        File file = new File(tempPath);
        File filex = new File(filePathx);

        String thepath = "";
        Long lastmodified = 0l;
        if (file.exists()) {
            lastmodified = file.lastModified();
        }
        Long lastmodifiedx = 0l;
        if (filex.exists()) {
            lastmodifiedx = filex.lastModified();
        }
        if (lastmodifiedx > lastmodified) {
            thepath = filePathx;
        }
        if (lastmodifiedx < lastmodified) {
            thepath = tempPath;
        }
        Workbook wb = null;

        FileInputStream readfout = null;
   
        try {
            readfout = new FileInputStream(thepath);
            wb =StreamingReader.builder().rowCacheSize(1000).bufferSize(4096).open(readfout);
         
            readfout.close();
    		RuleReferenceData inputRefeData = new RuleReferenceData();
    		inputRefeData.setCode(ruleTest.getModelCode());
    		inputRefeData.setVersion(ruleTest.getVersion());
    		inputRefeData.setContentType(ContentTypeEnum.in.code);
    		inputRefeData.setModelType(ruleTest.getModelType());
    		inputRefeData.setProjectCode(projectCode);
    		List<RuleDataModelVO> outputList = this.findReferenceData(inputRefeData);
    		
    		RuleReferenceData outputRefeData = new RuleReferenceData();
    		outputRefeData.setCode(ruleTest.getModelCode());
    		outputRefeData.setVersion(ruleTest.getVersion());
    		outputRefeData.setModelType(ruleTest.getModelType());
    		outputRefeData.setContentType(ContentTypeEnum.out.code);
    		outputRefeData.setProjectCode(projectCode);
    		List<RuleDataModelVO> outputList1 = this.findReferenceData(outputRefeData);
             
    		outputList.addAll(outputList1);
            if (outputList == null || outputList.size() == 0) {
                throw new BizException("");
            }
            RuleReferenceData refeData = null;
            Map<String,RuleReferenceData> refeMap =null;
            for (RuleDataModelVO refData:outputList) {
            	refeMap = new HashMap<>();
             	for (int j =0;j<refData.getAttrList().size();j++) {
             		refeData = refData.getAttrList().get(j);
             		if (!refeMap.containsKey(refeData.getNameen())) {
             			refeMap.put(refeData.getNameen(), refeData);
             		}else if (ContentTypeEnum.out.code.equals(refeData.getContentType())){
             			refeMap.put(refeData.getNameen(), refeData);
             		}
             	}
             	refData.setAttrList(new ArrayList<>(refeMap.values()));
             }
    	     Map<String, RuleReferenceData> paramMap = new HashMap<>();
    	     for (RuleDataModelVO ruleDataModelVO : outputList) {
    	        	for(RuleReferenceData ref:ruleDataModelVO.getAttrList()) {
    	        		paramMap.put(ruleDataModelVO.getClassName()+ref.getNameen(),ref);
    	        	}
    		}
            Sheet sheet = wb.getSheetAt(0);
            JSONObject json = new JSONObject();
            List<Object> toplist = new ArrayList<Object>();
            List<Object> list = new ArrayList<Object>();
            List<Object> list2 = new ArrayList<Object>();
            List<Object> list3 = new ArrayList<Object>();
            this.readRow(toplist, sheet, 0);
            this.readRow(list, sheet, 1);
            this.readRow(list2, sheet, 2);
            this.readRow(list3, sheet, 3);
            toplist.add(TESTTIME_CELL + spf.format(new Date()));
	        json.put(ExcelConstant.R, toplist);
	        json.put(ExcelConstant.R1, list);
	        json.put(ExcelConstant.R2, list2);
	        json.put(ExcelConstant.R3, list3);
	        System.out.println(" Excel 读取");
            List<List<Object>>  inputDatas = this.readInput(sheet);
            wb.close();
            System.out.println(" Excel 读取完成 ");
            this.writeExcelHeader(list3, outputList, paramMap,list2,list);
            List<Map<String, Object>> resultMaps= this.makeInputMap(inputDatas, list3,projectCode);
            RuleTestMap ruleTestMap = new RuleTestMap();
            ruleTestMap.setProjectCode(projectCode);
            ruleTestMap.setCode(ruleTest.getModelCode());
            ruleTestMap.setType(ruleTest.getModelType());
            ruleTestMap.setVersion(ruleTest.getVersion());

            RuleBatchResult  ruleBatchResult = this.ruleTestService.testBatchRule(ruleTestMap, resultMaps);
            SXSSFWorkbook   wrb  =null;
            wrb = new SXSSFWorkbook(1000);
            CellStyle style = wrb.createCellStyle();
            style.setAlignment(CellStyle.ALIGN_CENTER);	
	        System.out.println(" 写 Excel -----");
            CellStyle  cellStyle = wrb.createCellStyle();
            cellStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
            cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            SXSSFSheet  wSheet =  wrb.createSheet("index-1");
            this.writeRusultHeadText(json.getJSONArray(ExcelConstant.R), style, 0, wSheet);
            this.writeRusultHeadText(json.getJSONArray(ExcelConstant.R1), cellStyle, 1, wSheet);
            this.writeRusultHeadText(json.getJSONArray(ExcelConstant.R2), style, 2, wSheet);
            this.writeRusultHeadText(json.getJSONArray(ExcelConstant.R3), style, 3, wSheet);
            this.writeExcuteTime(wrb.createCellStyle(), wSheet,ruleBatchResult.getExecuteDateTime() );
            writeSingleExcuteTime(wrb.createCellStyle(),wSheet,list3.size());
            Map<String, List<RuleDataDomain>> getThendmsDomain = getThendmsDomain(outputList, projectCode);
        
            RuleBatchResultVO batchResultVO = null;
            RuleInputVO inputVO  = null;
            Iterator<RuleInputVO> iter= ruleBatchResult.getRuleSingleTest().getInputList().iterator();
            Map<String,String> attrMap =this.attrNameZhcn(outputList);
            int j=0;
            while  (iter.hasNext()) {
            	inputVO = iter.next();
            	Map<String, Object> rusultMaps = new HashMap<String, Object>();
            	Map<String,Object>  input = inputVO.getInputMaps();
                toRusultList(input, rusultMaps);
                batchResultVO  = new RuleBatchResultVO();
                batchResultVO.setResMap(rusultMaps);
                batchResultVO.setExeTime(inputVO.getExecTime());
                iter.remove();
                this.writeExcleRusult(wSheet, list3, batchResultVO, attrMap, getThendmsDomain, j);
                j++;
            }
            System.out.println(" 写 Excel 完成-----");
            this.createExcelFile(wrb, ruleTest);
            ruleTest.setStatus("11");//
            this.save(ruleTest);
        } catch (Exception e) {
            e.printStackTrace();
            throw  new  BizException(e, "");
        }
        
    }
    
    @SuppressWarnings("unchecked")
	private   List<Map<String, Object>>  makeInputMap(List<List<Object>> inputDatas,List<Object> list3,String projectCode){
    	 Map<String,DataSetVO> fMap =this.fieldMapping(projectCode);
        List<Map<String, Object>>  reList = new  ArrayList<>();
        for(int i =0; i<inputDatas.size();i++ ) {
        	List<Object> rList = inputDatas.get(i);
        	int  len = rList.size(); 
            Map<String,Object> inpMap  =new HashMap<>();
        	reList.add(inpMap);
        	for(int  k =1;k<list3.size();k++) {
        		String   clazzName =  list3.get(k).toString();
        		DataSetVO dataSetVO =fMap.get(clazzName);
        		if(dataSetVO==null) {
        			throw new RuntimeException("未找到该数据集["+clazzName+"]");
        		}
        		Map<String,Object>   fvMap  = null;
        		MField  field  = dataSetVO.getMfield();
        		String className = dataSetVO.getClazzName();
        		int  j = k-1;
        		Object  val =null;
        		if (len >= k)
        		  val = rList.get(j);
        		if (inpMap.get(className) == null) {
        				 fvMap = new  HashMap<>();
        				 inpMap.put(className, fvMap);
        				 if (len< k) {
        					 fvMap.put(field.getName(),null);
        				 }else {
        				   if (field.getType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_LONG)) {
          				     
        					  if (!StringUtils.isEmpty(val.toString())) {
        						  fvMap.put(field.getName(),Math.round(Double.parseDouble(val.toString())) ); 
        					  }else {
        						  fvMap.put(field.getName(),null);
        					  }
        				   }else if (StringUtils.isNotBlank(field.getDomain())) {
                              Map<String,List<RuleDataDomain>> map = this.dataBomService.findDomainMap();
                              List<RuleDataDomain> domainList = map.get(field.getDomain());
                               for (RuleDataDomain item : domainList) {
                            	   if (!StringUtils.isEmpty(val.toString())) {
	                                   if ( item.getName().equals(val.toString())) {
	                                	   fvMap.put(field.getName(),item.getDomainValue());
	                                       break;
	                                   }
                            	   }else {
                               		  fvMap.put(field.getName(), null);
                               		  break;
                            	   }
                               }
        				   }else {
        					   fvMap.put(field.getName(),rList.get(j));
        				   }
        				   
        				 }  
        				  
        		}else {
        				 fvMap=(Map<String, Object>) inpMap.get(className);
        				 if (len < k) {
        					 fvMap.put(field.getName(),null); 
        				 }else {
          				   if (field.getType().equals(Constant.DATAMODEL_ATTRIBUTE_TYPE_LONG)) {
         					  if (!StringUtils.isEmpty(val.toString())) {
         						  fvMap.put(field.getName(),Math.round(Double.parseDouble(val.toString())) ); 
         					  }else {
         						  fvMap.put(field.getName(),null);
         					  }
         				   }else if (StringUtils.isNotBlank(field.getDomain())) {
                               Map<String,List<RuleDataDomain>> map = this.dataBomService.findDomainMap();
                               List<RuleDataDomain> domainList = map.get(field.getDomain());
                                for (RuleDataDomain item : domainList) {
                                	if (!StringUtils.isEmpty(val.toString())) {
	                                    if ( item.getName().equals(val.toString())) {
	                                 	   fvMap.put(field.getName(),item.getDomainValue());
	                                        break;
	                                    }
                                	}else {
                                		fvMap.put(field.getName(), null);
                                		break;
                                	}
                                }
         				   }else {
         					   
         					  fvMap.put(field.getName(),val);
         				    }  
        				}	 
        		}
        		
        	
        	}
        }
        return reList;
   
    }
    
    private   void    writeExcuteTime(CellStyle style,Sheet sheet,Long executeDateTime) {
  	  Row  row  = sheet.getRow(0);
  	  int  lastCellNum = row.getLastCellNum()+1;
  	  Cell cell =row.createCell(lastCellNum);
  	  style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
  	  style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  	  style.setAlignment(CellStyle.ALIGN_CENTER);
  	  cell.setCellStyle(style);
  	  cell.setCellValue("总执行时间："+executeDateTime);
  	
  }
    
    
    private  void   writeSingleExcuteTime(CellStyle style,Sheet sheet,int  colNum) {
  	      Row  row  = sheet.getRow(3);
	  	  Cell cell =row.createCell(colNum);
	  	  style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
	  	  style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	  	  style.setAlignment(CellStyle.ALIGN_CENTER);
	  	  cell.setCellStyle(style);
	  	  cell.setCellValue("执行时间");

  	
  }
    
   private  String  getCreateExcelFile(RuleTest  ruleTest) {
        String resultBasePath = Global.getConfig("file.uploadRoot") + File.separator + ruleTest.getProjectCode() + RuleTest.RUSULT_EXT;
        File f = new File(resultBasePath);
        // 创建文件夹
        if (!f.exists()) {
            f.mkdirs();
        }
        String resultExcleFile = resultBasePath + File.separator + ruleTest.getId() +".xlsx";

        return  resultExcleFile;
    }
    
    public   void   createExcelFile(Workbook wb,RuleTest  ruleTest) {

        try { 
            FileOutputStream fout = new FileOutputStream(this.getCreateExcelFile(ruleTest));
            wb.write(fout);
            fout.close();
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
        }finally {
        	try {
				wb.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

        }
    }
    
    
    private   void   writeExcelHeader(List<Object> list3,List<RuleDataModelVO> dataList,Map<String, RuleReferenceData> paramMap,List<Object> list2,List<Object> list) {
        int countAttr = 0;
    	for (RuleDataModelVO dm : dataList) {
            if (dm.getAttrList().size() > 0 && dm.getAttrList().get(0) != null) {
            	int size = 0;
                for (Entry<String ,RuleReferenceData> entry : paramMap.entrySet()) {
                	if(!dm.getClassName().equals(entry.getValue().getClassName())) 
                		continue;
                	if(list3.contains(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn())) {
                		continue;
                	}
                		
                	list3.add(entry.getValue().getClassNamecn()+"."+entry.getValue().getNamecn());
                	countAttr++;
                	size++;

        		}
                if (size>0) {
                   list2.add(dm.getClassNamecn() + "##" + size);
                }
            }
        }
        if (countAttr > 1) {
            list.add(ExcelConstant.RESULT_CELL + "##" + countAttr);
        } else {
            list.add(ExcelConstant.RESULT_CELL);
        }
    }
    
 


    private   void writeRusultHeadText(List<Object> getList, CellStyle style, int  rowNum, SXSSFSheet sheet) {
        int preLength = 0;
        int k = 0;
        SXSSFRow  row =null;
        row = sheet.getRow(rowNum);
        if (row == null) {
        	row = sheet.createRow(rowNum);
        }
        for (int i = 0; i <  getList.size(); i++) {
            Cell cell = row.createCell((short) i + preLength);
            k = i ;
            cell.setCellValue(getValue(getList.get(k).toString()));
            int lastColIndex = cell.getColumnIndex() + Integer.valueOf(getColSpan(getList.get(k).toString())) - 1;
            cell.setCellStyle(style);
            if ((cell.getColumnIndex()) < lastColIndex)
                sheet.addMergedRegion(new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), lastColIndex));
            preLength = preLength + Integer.valueOf(getColSpan(getList.get(k).toString())) - 1;
        }
    }



   public  Map<String,DataSetVO>  fieldMapping(String  projectCode){
	   Map<String, MClass> metaMap = this.dataBomService.findMapClass(projectCode);
	   Map<String,DataSetVO>  rMap  = new  HashMap<>();
       for(String className:metaMap.keySet()) {
	   		MClass mclass = metaMap.get(className);
			Map<String,MField> fieldMap = mclass.getFieldMap();
			for(String name:fieldMap.keySet()) {
				    DataSetVO  dataSetVO  = new  DataSetVO();
					MField mField = fieldMap.get(name);
					String dmpkey = mclass.getChzn()+"."+mField.getChzn();
					dataSetVO.setClazzName(className);
					dataSetVO.setMfield(mField);
					rMap.put(dmpkey, dataSetVO);
			}
       }
       return   rMap;
   }

 
    @Override
    public void delBatchTest(String id, String projectCode) throws BizException {
        RuleTest ruleTest = this.get(id);
        String uploadRoot = Global.getConfig("file.uploadRoot");
        //上传文件
        String perixFile = uploadRoot + File.separator + projectCode + RuleTest.UPDATE_BASE_PATH + File.separator + ruleTest.getId();
        String uploadFile = perixFile + ".xls";
        File file = new File(uploadFile);
        if (file.exists()) {
            file.delete();
        }
        uploadFile = perixFile + ".xlsx";
        file = new File(uploadFile);
        if (file.exists()) {
            file.delete();
        }
        //结果文件
        String resultFile = uploadRoot + File.separator + projectCode + RuleTest.RUSULT_EXT + File.separator + ruleTest.getId() + ".xlsx";
        File rFile = new File(resultFile);
        if (rFile.exists()) {
            rFile.delete();
        }
        this.delete(ruleTest);

    }

     @SuppressWarnings("unchecked")
    private void toRusultList(Map<String, Object> input, Map<String, Object> rusultMaps) {
    	String  clzName =null; 
        for (Map.Entry<String, Object> inputEntry : input.entrySet()) {
            clzName = inputEntry.getKey();
        	if (clzName.equals("tracks")) {
                continue;
            }
            Map<String, Object> temp =(Map<String, Object>) inputEntry.getValue();
            for (Map.Entry<String, Object> entry : temp.entrySet()) {
                    rusultMaps.put(clzName+"."+entry.getKey(), entry.getValue());
            }
        }
    }

    private Map<String, List<RuleDataDomain>> getThendmsDomain(List<RuleDataModelVO> thendms, String projectCode) throws BizException {
        Map<String, List<RuleDataDomain>> getThendmsDomain = new HashMap<String, List<RuleDataDomain>>();
        List<RuleDataDomain> list = null;
        for (RuleDataModelVO dm : thendms) {
            for (RuleReferenceData attr : dm.getAttrList()) {
                if (attr == null) {
                    break;
                }
                if (!StringUtils.isEmpty(attr.getDomain())) {
                	Map<String, List<RuleDataDomain>> map = this.dataBomService.findDomainMap();
                	list  =  map.get(attr.getDomain());
                    if (list != null && list.size() > 0)
                        getThendmsDomain.put(attr.getClassName()+"."+attr.getNameen(), list);
                }
            }
        }
        return getThendmsDomain;
    }
    
    private  Map<String,String>  attrNameZhcn(List<RuleDataModelVO> thendms){
        List<RuleReferenceData> tmpList = new ArrayList<RuleReferenceData>();
        for (RuleDataModelVO dataModelVO : thendms) {
            tmpList.addAll(dataModelVO.getAttrList());
        }
        Map<String, String> atrrNameZhcnMap = AtrrNameZhcnMap(tmpList);
        return atrrNameZhcnMap;  
    }
    
    private void writeExcleRusult(SXSSFSheet wSheet ,List<Object> list3, RuleBatchResultVO  batchResultVO,Map<String,String> atrrNameZhcnMap ,  Map<String, List<RuleDataDomain>> getThendmsDomain,int  j) {

        Map<String,Object>  rusultMaps   = null;
        int  n  =0;
        //int  j=0;
        int  len  = list3.size();
        //for (RuleBatchResultVO  batchResultVO:resList) { 
        	rusultMaps = batchResultVO.getResMap();
        	n  = j+4;
        	Row  row =  wSheet.createRow(n);
	        for (int i = 1; i < len; i++) {
	            String getStringCellValue = list3.get(i).toString();
	            
	            if(atrrNameZhcnMap.containsKey(getStringCellValue)) {
	            	String key = atrrNameZhcnMap.get(getStringCellValue);
	            	if (rusultMaps.get(key) != null) {
	                	Object  val  = rusultMaps.get(key);
	                    String valString = "";
	                    if (val != null) {
	                        valString = val.toString();
	                    }
	                    if (getThendmsDomain.get(key) != null) {
                            List<RuleDataDomain> itmes = getThendmsDomain.get(key);
                            for (RuleDataDomain item : itmes) {
                                if (item.getDomainValue().equals(valString)) {
                                    valString = item.getName();
                                    break;
                                }
                            }
	                    }
	                    Cell cell = row.createCell(i);  
	                    cell.setCellValue(valString);  
	                 }
	            }
	          
	       }
	       Cell cell =row.createCell(len);
	       cell.setCellValue(batchResultVO.getExeTime());
         
 
       //}

    }   


    //多线程
    class SubTask extends RecursiveAction {

        private static final long serialVersionUID = 1L;

        private Map<String, List<Object>> inputMaps;
        private int beg;
        private int end;
        private String type;

        Sheet sheet;

        List<RuleDataModelVO> dataModelList;
        Map<String, List<RuleDataDomain>> getThendmsDomain;

        public SubTask(Map<String, List<Object>> inputMaps, int beg, int end, String type, Sheet sheet, List<RuleDataModelVO> dataModelList, Map<String, List<RuleDataDomain>> getThendmsDomain) {
            super();
            this.inputMaps = inputMaps;
            this.beg = beg;
            this.end = end;
            this.type = type;

            this.sheet = sheet;
            this.dataModelList = dataModelList;
            this.getThendmsDomain = getThendmsDomain;
        }


        @Override
        protected void compute() {
            if (end - beg > EXR_DROOL_EXR_RPE_SIZE) {
                int mid = (beg + end) / 2;
                if (sheet != null) {
                    SubTask t1 = new SubTask(inputMaps, beg, mid, type, sheet, this.dataModelList, getThendmsDomain);
                    SubTask t2 = new SubTask(inputMaps, mid, end, type, sheet, this.dataModelList, getThendmsDomain);
                    invokeAll(t1, t2);
                }

            } else {
                try {
                    if (sheet != null) {
                        writeRusult(sheet, inputMaps, this.dataModelList, getThendmsDomain, beg, end);
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    //e.printStackTrace();
                    LoggerManager.error("", e, this.getClass());
                }
            }
        }
    }

    private void writeRusult(Sheet sheet, Map<String, List<Object>> rusultMaps, List<RuleDataModelVO> thendms, Map<String, List<RuleDataDomain>> getThendmsDomain, int beg, int end) {
        List<RuleReferenceData> tmpList = new ArrayList<RuleReferenceData>();
        for (RuleDataModelVO dataModelVO : thendms) {
            tmpList.addAll(dataModelVO.getAttrList());
        }
        Map<String, String> atrrNameZhcnMap = AtrrNameZhcnMap(tmpList);
        Row row = sheet.getRow(3);
        for (int i = 1; i < row.getLastCellNum(); i++) {
            String getStringCellValue = row.getCell(i).getStringCellValue().toString();
            if(atrrNameZhcnMap.containsKey(getStringCellValue)) {
                String key = atrrNameZhcnMap.get(getStringCellValue);
                int k = 4 + beg;
                if (rusultMaps.get(key) != null) {
                    for (Object val : (rusultMaps.get(key).subList(beg, end))) {
                        Row r = sheet.getRow(k);

                        Cell cell = r.createCell((short) i);
                        String valString = "";
                        if (val != null) {
                            valString = val.toString();
                        }
                        if (getThendmsDomain.get(key) != null) {
                            List<RuleDataDomain> itmes = getThendmsDomain.get(key);
                            for (RuleDataDomain item : itmes) {
                                if (item.getDomainValue().equals(valString)) {
                                    valString = item.getName();
                                    break;
                                }
                            }
                        }
                        System.out.println("++" + valString);
                        cell.setCellValue(valString);
                        if (k >= end + 4) {
                            break;
                        }
                        k++;
                    }
                }
            }
        }

    }

}